package org.sky.action;

import com.opensymphony.xwork2.ModelDriven;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.sky.base.PageView;
import org.sky.model.Authority;
import org.sky.model.Person;
import org.sky.security.MD5;
import org.sky.service.AuthoritiesService;
import org.sky.service.PersonService;
import org.sky.vo.PersonVO;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Component("person")
@Scope("prototype")
public class PersonAction extends MyActionSupport implements ModelDriven<PersonVO> {
    private final static Logger logger = LogManager.getLogger(PersonAction.class.getName());
    private PersonService personService;
    private AuthoritiesService authoritiesService;
    private PersonVO personVO = new PersonVO();
    private Person person = new Person();

    /* UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
private final String username = userDetails.getUsername();*/


    //显示后台用户
    public String execute() {
        /** 每页显示的结果数 **/
        int maxResult = 6;
        /** 封装的页面数据 **/
        PageView<Person> pageView = new PageView<Person>(maxResult,
                personVO.getPage());
        int firstIndex = ((pageView.getCurrentPage() - 1) * pageView
                .getMaxResult());// 开始索引
        // 按照条件排序
        LinkedHashMap<String, String> orderBy = new LinkedHashMap<String, String>();
        orderBy.put("enabled", "desc");
        orderBy.put("id", "desc");
        /** 列表条件 **/
        StringBuffer jpql = new StringBuffer("1=1");
        /** 列表条件的值 **/
        List<Object> params = new ArrayList<Object>();
        if ("true".equals(personVO.getQuery())) {
            //按用户名查找
            if (personVO.getUserName() != null && !"".equals(personVO.getUserName())) {
                jpql.append(" and o.userName like ?").append((params.size() + 1));
                params.add("%" + personVO.getUserName() + "%");
            }
            //按邮箱查找
            if (personVO.getEmail() != null && !"".equals(personVO.getEmail())) {
                jpql.append(" and o.email like ?").append((params.size() + 1));
                params.add("%" + personVO.getEmail() + "%");
            }
            //按手机查找
            if (personVO.getPhone() != null && !"".equals(personVO.getPhone())) {
                jpql.append(" and o.phone like ?").append((params.size() + 1));
                params.add("%" + personVO.getPhone() + "%");
            }
            //按权限查找
            if (personVO.getAuthority() != null && !"".equals(personVO.getAuthority().toString())) {
                jpql.append(" and o.authority like ?").append((params.size() + 1));
                params.add("%" + personVO.getAuthority().getName() + "%");
            }
            //按信誉区间查找
            if (personVO.getStartCredit() > 0) {
                jpql.append(" and o.credit >= ?").append((params.size() + 1));
                params.add(personVO.getStartCredit());
            }
            if (personVO.getEndCredit() > 0) {
                jpql.append(" and o.credit <= ?").append((params.size() + 1));
                params.add(personVO.getEndCredit());
            }
            //按使用次数区间查找
            if (personVO.getStartLevel() > 0) {
                jpql.append(" and o.level >= ?").append((params.size() + 1));
                params.add(personVO.getStartLevel());
            }
            if (personVO.getEndLevel() > 0) {
                jpql.append(" and o.level <= ?").append((params.size() + 1));
                params.add(personVO.getEndLevel());
            }
            jpql.append(" and o.authority != ?").append((params.size() + 1));
            params.add(Authority.ROLE_USER.getName());
            pageView.setQueryResult(personService.getScrollData(Person.class, firstIndex, maxResult, jpql.toString(), params.toArray(), orderBy));
            personVO.setQuery("true");
        } else {
            jpql.append(" and o.authority != ?").append((params.size() + 1));
            params.add(Authority.ROLE_USER.getName());
            pageView.setQueryResult(personService.getScrollData(Person.class, firstIndex, maxResult, jpql.toString(), params.toArray(), orderBy));
        }
        personVO.setPageView(pageView);
        view = "/page/person/personlist.jsp";
        return VIEW;
    }

    //显示后台用户
    public String userList() {
        /** 每页显示的结果数 **/
        int maxResult = 6;
        /** 封装的页面数据 **/
        PageView<Person> pageView = new PageView<Person>(maxResult,
                personVO.getPage());
        int firstIndex = ((pageView.getCurrentPage() - 1) * pageView
                .getMaxResult());// 开始索引
        // 按照条件排序
        LinkedHashMap<String, String> orderBy = new LinkedHashMap<String, String>();
        orderBy.put("enabled", "desc");
        orderBy.put("id", "desc");
        /** 列表条件 **/
        StringBuffer jpql = new StringBuffer("1=1");
        /** 列表条件的值 **/
        List<Object> params = new ArrayList<Object>();
        if ("true".equals(personVO.getQuery())) {
            //按用户名查找
            if (personVO.getUserName() != null && !"".equals(personVO.getUserName())) {
                jpql.append(" and o.userName like ?").append((params.size() + 1));
                params.add("%" + personVO.getUserName() + "%");
            }
            //按邮箱查找
            if (personVO.getEmail() != null && !"".equals(personVO.getEmail())) {
                jpql.append(" and o.email like ?").append((params.size() + 1));
                params.add("%" + personVO.getEmail() + "%");
            }
            //按手机查找
            if (personVO.getPhone() != null && !"".equals(personVO.getPhone())) {
                jpql.append(" and o.phone like ?").append((params.size() + 1));
                params.add("%" + personVO.getPhone() + "%");
            }
            //按信誉区间查找
            if (personVO.getStartCredit() > 0) {
                jpql.append(" and o.credit >= ?").append((params.size() + 1));
                params.add(personVO.getStartCredit());
            }
            if (personVO.getEndCredit() > 0) {
                jpql.append(" and o.credit <= ?").append((params.size() + 1));
                params.add(personVO.getEndCredit());
            }
            //按使用次数区间查找
            if (personVO.getStartLevel() > 0) {
                jpql.append(" and o.level >= ?").append((params.size() + 1));
                params.add(personVO.getStartLevel());
            }
            if (personVO.getEndLevel() > 0) {
                jpql.append(" and o.level <= ?").append((params.size() + 1));
                params.add(personVO.getEndLevel());
            }
            jpql.append(" and o.authority = ?").append((params.size() + 1));
            params.add(Authority.ROLE_USER.getName());
            pageView.setQueryResult(personService.getScrollData(Person.class, firstIndex, maxResult, jpql.toString(), params.toArray(), orderBy));
            personVO.setQuery("true");
        } else {
            jpql.append(" and o.authority = ?").append((params.size() + 1));
            params.add(Authority.ROLE_USER.getName());
            pageView.setQueryResult(personService.getScrollData(Person.class, firstIndex, maxResult, jpql.toString(), params.toArray(), orderBy));
        }
        personVO.setPageView(pageView);
        view = "/page/person/userlist.jsp";
        return VIEW;
    }

    //账号状态改变
    public String personState() {
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        final String username = userDetails.getUsername();
        String state = personVO.getMethod();
        String[] userNames = personVO.getUserNames();
        String message = "";
        if (state.equals("enable")) {
            personService.setPersonEnable(userNames, true);
            message = "启用用户成功";
            logger.trace("User:" + username + " invoke userName:" + personVO.getUserNames());
        } else if (state.equals("disable")) {
            personService.setPersonEnable(userNames, false);
            message = "停用用户成功";
            logger.trace("User:" + username + " stop userName:" + personVO.getUserNames());
        } else {
            personVO.setResultMessage("<script>alert('操作失败，该用户账号已存在或该用户属性为空！');location.href='Person!userList.action';</script>");
            return ERROR;
        }
        personVO.setResultMessage("<script>alert('" + message + "');location.href='Person!userList.action';</script>");
        return SUCCESS;
    }

    //用户注册
    public String register() {
        if (personVO.getUserName().equals("")) {
            personVO.setResultMessage("<script>alert('操作失败，用户的帐号不能为空!');location.href='/page/person/register.jsp';</script>");
            return ERROR;
        } else if (!isExistedAccount() && !personVO.getUserName().equals("")
                && !personVO.getEmail().equals("") && !personVO.getPassword().equals("")) {
            person.setUserName(personVO.getUserName());
            person.setPassword(MD5.getMD5ofStr(personVO.getPassword(), 4));
            person.setPhone(personVO.getPhone());
            person.setEmail(personVO.getEmail());
            person.setAuthority(Authority.ROLE_USER.getName());
            personService.save(person);
            logger.trace("User: " + person.getUserName() + "  register!");
            personVO.setResultMessage("<script>alert('注册成功');location.href='/login.jsp';</script>");
            return SUCCESS;
        } else {
            personVO.setResultMessage("<script>alert('操作失败，该用户账号已存在或该用户属性为空!');location.href='/page/person/register.jsp';</script>");
            return ERROR;
        }
    }

    //密码修改
    public String changePassword() {
        if ("".equals(personVO.getPassword()) || "".equals(personVO.getUpdatePassword())) {
            personVO.setResultMessage("<script>alert('请输入当前用户密码或修改的用户密码！');location.href='/page/person/changePassword.jsp';</script>");
            return ERROR;
        }

        person = personService.findPersonByUserName(personVO.getUserName());

        if (person == null || !person.isEnabled()) {
            personVO.setResultMessage("<script>alert('当前用户停止使用！请与管理员联系');location.href='/index.jsp';</script>");
            return ERROR;
        }

        if (!MD5.verifyPassword(personVO.getPassword(), person.getPassword(), 4)) {
            personVO.setResultMessage("<script>alert('原密码不正确！请重新输入！');location.href='/page/person/changePassword.jsp';</script>");
            return ERROR;
        }

        if (MD5.verifyPassword(personVO.getUpdatePassword(), person.getPassword(), 4)) {
            personVO.setResultMessage("<script>alert('原密码与新密码不能相同！请重新输入！');location.href='/page/person/changePassword.jsp';</script>");
            return ERROR;
        }

        person.setPassword(MD5.getMD5ofStr(personVO.getUpdatePassword(), 4));
        personService.update(person);
        personVO.setResultMessage("<script>alert('密码修改成功!');location.href='/login.jsp';</script>");
        logger.trace(person.getUserName() + " password changed! new password is " + personVO.getUpdatePassword());
        return SUCCESS;
    }

    //忘记密码
    public String forgotPassword() {
        if ("".equals(personVO.getUserName()) || "".equals(personVO.getEmail()) || "".equals(personVO.getPhone())) {
            personVO.setResultMessage("<script>alert('请正确填写信息！');location.href='/page/person/forgotPassword.jsp';</script>");
            return ERROR;
        }

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userName", personVO.getUserName());
        params.put("email", personVO.getEmail());
        params.put("phone", personVO.getPhone());
        person = (Person) personService.findSpecialObject(Person.class, params);
        if (person == null) {
            personVO.setResultMessage("<script>alert('没有此用户信息！请核实！');location.href='/page/person/forgotPassword.jsp';</script>");
            return ERROR;
        }
        if (personVO.getFlag() == 1) {
            view = "/page/person/forgotPassword.jsp";
            return VIEW;
        } else {
            person.setPassword(MD5.getMD5ofStr(personVO.getPassword(), 4));
            personService.update(person);
            personVO.setResultMessage("<script>alert('重设密码成功！请重新登录！');location.href='/login.jsp';</script>");
            personVO.setFlag(1);
            return SUCCESS;
        }
    }

    //用户添加
    public String addPerson() {
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        final String username = userDetails.getUsername();

        if (personVO.getUserName().equals("")) {
            personVO.setResultMessage("<script>alert('操作失败，用户的帐号不能为空!');location.href='/page/person/addPerson.jsp';</script>");
            return ERROR;
        } else if (!isExistedAccount() && !personVO.getUserName().equals("")
                && !personVO.getEmail().equals("") && !personVO.getPassword().equals("")) {
            personVO.setEnabled(true);
            copyDefaultPersonInfo(person, personVO);
            personService.save(person, personVO.getAuthority());
            logger.trace(username + " add a User:" + person.getUserName());
            personVO.setResultMessage("<script>alert('操作成功，成功添加用户!');location.href='Person!userList.action';</script>");
            return SUCCESS;
        } else {
            personVO.setResultMessage("<script>alert('操作失败，该用户账号已存在或该用户属性为空!');location.href='/page/person/addPerson.jsp';</script>");
            return ERROR;
        }
    }

    //读取用户记录
    public String loadPerson() {
        person = personService.find(Person.class, personVO.getId());
        personVO.setPerson(person);
        view = "/page/person/update.jsp";
        return VIEW;
    }

    //更新用户
    public String updatePerson() {
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        final String username = userDetails.getUsername();
        person = personService.find(Person.class, personVO.getId());
        if (person != null && !personVO.getEmail().equals("") && !personVO.getPassword().equals("")
                && !String.valueOf(personVO.getCredit()).equals("")
                && !String.valueOf(personVO.getLevel()).equals("") && personVO.getPhone().trim().length() == 11) {
            person.setCredit(personVO.getCredit());
            person.setEmail(personVO.getEmail());
            person.setPhone(personVO.getPhone());
            person.setLevel(personVO.getLevel());
            person.setLevel(personVO.getLevel());
            person.setEnabled(personVO.isEnabled());
            personService.changeAuthority(person, personVO.getAuthority());
            if (!personVO.getPassword().equals(person.getPassword())) {
                person.setPassword(MD5.getMD5ofStr(personVO.getPassword(), 4));
            }
            personService.update(person);
            personVO.setResultMessage("<script>alert('用户信息更新成功!');location.href='Person!userList.action';</script>");
            logger.trace(username + " update message");
            return SUCCESS;

        } else {
            personVO.setResultMessage("<script>alert('操作失败，该用户属性为空!');location.href='Person!loadPerson.action?id=" + person.getId() + "';</script>");
            return ERROR;
        }
    }

    //用户是否存在
    private boolean isExistedAccount() {
        return personService.findPersonByUserName(personVO.getUserName()) != null;
    }

    @Resource(name = "personServiceImpl")
    public void setPersonService(PersonService personService) {
        this.personService = personService;
    }

    @Resource(name = "authoritiesServiceImpl")
    public void setAuthoritiesService(AuthoritiesService authoritiesService) {
        this.authoritiesService = authoritiesService;
    }

    @Override
    public PersonVO getModel() {
        return personVO;
    }

    private Person copyDefaultPersonInfo(Person targetPerson, PersonVO personVO) {
        targetPerson.setUserName(personVO.getUserName());
        targetPerson.setPassword(MD5.getMD5ofStr(personVO.getPassword(), 4));
        targetPerson.setPhone(personVO.getPhone());
        targetPerson.setEmail(personVO.getEmail());
        targetPerson.setAuthority(personVO.getAuthority().getName());
        targetPerson.setCredit(personVO.getCredit());
        targetPerson.setEnabled(personVO.isEnabled());
        targetPerson.setLevel(personVO.getLevel());
        return targetPerson;
    }
}
